/**
 * Spell
 * Template of Player's spell
 **/
var Spell = function() {
// CONFIGURATION ---
	// CARACTERISTICS
	this.target		= {x:0,y:0}; 					//Where spell goes
	this.bounds		= {w:0,h:0}; 					//Hit box

	this.name 	 	= SpellConf.name;				//Name

	this.damage		= SpellConf.damage.min;			//Damage inflicted to target
	this.cooldown 	= SpellConf.cooldown.min;		//Waiting time between 2 spells
	this.distance 	= SpellConf.distance.min; 		//Distance from player spell can be created
	this.size 		= SpellConf.size.min;			//Size of spell
	this.multi 		= SpellConf.multi.min;			//Number of target can be hit

	this.effect	 	= SpellConf.effect.list[0];		//Type of effect on target (none / stun / pushBack / poison / heal)
	this.element	= SpellConf.element.list[0];		//Element of spell

	this.icon		= SpellConf.icon;				//Preview icon
// --- END CONFIGURATION
}
// SPELLBOOK ENTRY METHODS ---
	// FORMAT ---
	Spell.prototype.unserialize = function(json) {
		var obj = JSON.parse(json);
		for(prop in obj) {
			this[prop] = obj[prop];

			switch(prop) {
				case 'icon' :
				break;
			}
		}
	}

	Spell.prototype.serialize = function() {
		var obj = {};
		for(prop in this) {
			if(typeof this[prop] !== "function") {

				switch(prop) {
					case 'img' : 
					break;

					default :
						obj[prop] = this[prop];
					break;
				}
			}
		}

		return JSON.stringify(obj);
	}
	// --- END FORMAT

	// MANAGE ---
	Spell.prototype.save = function() {
		var json = this.serialize();
		localStorage.setItem(this.name, json);
		this.unserialize(json);
	}

	Spell.prototype.delete = function(name) {
		localStorage.removeItem(name);
	}
	// --- END MANAGE

	// TEMPLATE ---
	Spell.prototype.show = function() {
		for (prop in this) {
			if (typeof this[prop] !== "function") {
				switch (prop) {
					case 'element' : 	if ($('#element')) {
										var list = SpellConf.element.list;
										var selected = this[prop];
										var options = '';
										for (var iL = 0, cL = list.length; iL < cL; iL++) {
											var select = '';
											if(selected == list[iL]) {
												select = 'selected="selected"';
											}
											options += '<option '+select+'>'+list[iL]+'</option>';
										}
										$('#element').innerHTML = options;
									}
									break;

					case 'cooldown' : 	$('#cooldown').innerHTML = this[prop];
									break;

					default : 	if ($('#'+prop)) {
									$('#'+prop).value = this[prop];
									if (isNumber(this[prop]) && typeof SpellConf[prop] != "undefined") {
										$('#'+prop).setAttribute('min', SpellConf[prop].min);
										$('#'+prop).setAttribute('max', SpellConf[prop].max);
									}
								}
								break;
				}
			}
		}
	}
	// --- END TEMPLATE

	Spell.prototype.getImage = function() {

		var img = 'img/icon/spells/512x512/'+this.icon+'.png';		
		return img;
	}

	Spell.prototype.getCooldown = function() {

		var cooldown = ((this.damage * (this.distance/100)) * this.multi) / this.size;
		
		if(cooldown < SpellConf.cooldown.min) {
			cooldown = SpellConf.cooldown.min;
		}
		else if(cooldown > SpellConf.cooldown.max) {
			cooldown = SpellConf.cooldown.max;
		}

		return Math.round(cooldown);
	}

// --- END SPELLBOOK ENTRY METHODS

// INGAME SPELL METHODS ---
	Spell.prototype.summon = function() {
		// Initialize instance of spell
		var obj = {};
		// Get all properties of spell
		for(prop in this) {
			if(isNumber(this[prop]) == true) {
				obj[prop] = parseInt(this[prop]);
			}
			else {
				obj[prop] = this[prop];	
			}
		}
		// Set coords according to player position
		obj.coords = {
			x : PlayerConf.coords.x - PlayerConf.bounds.w/2,
			y : PlayerConf.coords.y + PlayerConf.bounds.h*.75
		}

		// Initialize rotation
		obj.rotation = 0;

		// Create particles for spell
		obj.anim = new ParticleGenerator();

		// Initialize particles according to element
		if(typeof obj.anim[this.element] != "undefined") {
			obj.anim[this.element](obj);
		}
		// Or by default element
		else {
			obj.anim.fire(obj);
		}

		// Set cooldown
		obj.cooldown = this.getCooldown();

		// Initialize garbage flag
		obj.toGarbage = false;

		// Return instance
		return obj;
	}

	Spell.prototype.update = function() {
		// Set physic object for spell
		var phySpell = {
			x : this.coords.x - this.size/2,
			y : this.coords.y - this.size/2,
			w : this.size,
			h : this.size
		};

		// Parse list of enemies
		for(var iE = 0, cE = game.mEnemy.entities.length; iE < cE; iE++) {
			// Get enemy
			var e = game.mEnemy.entities[iE];
			
			// If spell collide with enemy, lose life
			if(collide(phySpell, e) == true && this.multi > 0 && this.anim.toExplode == false) {
				// Decrease life of enemy
				e.life -= this.damage;
				this.multi--;
			}
			else if(this.multi <= 0) {
				// Call explode animation
				this.anim.explode();
				// Break loop if spell is destroy
				break;
			}
		}


		// Change state of particles animation
		if(this.coords.x > PlayerConf.coords.x + this.distance*.75 && this.anim.toExplode == false) {
			this.anim.explode();
		}
		// Move spell
		else{
			this.coords.x += (SpellConf.size.max + 5) - this.size;
		}

		// Destroy spell
		if(this.coords.x > PlayerConf.coords.x + this.distance) {
			this.destroy();
		}

		deltaTime = ( Date.now() - deltaTime ) / 1000;
		this.rotation -= 0.01 * deltaTime;

		this.anim.update();
	}

	Spell.prototype.render = function() {
		CTX.save();	
		CTX.translate(this.coords.x-this.size/2, this.coords.y-this.size/2);
		CTX.rotate(this.rotation);
		this.anim.render();
		CTX.restore();
	}

	Spell.prototype.debug = function() {
		CTX.fillStyle = "rgba(255,255,255,.3)";
		CTX.fillRect(this.coords.x-this.size/2, this.coords.y-this.size/2, this.size, this.size);
	}

	Spell.prototype.destroy = function() {
		this.toGarbage = true;
	}

// --- INGAME SPELL METHODS
